// 用户管理控制器
// 加载模型
const User = require('../models/user.model');
const Role = require('../models/role.model'); // 导入 Role 模型

const { Op } = require('sequelize'); // 导入 Sequelize 的 Op 对象，用于模糊搜索
const dateFormatter = require('../utils/dateFormatter'); // 引入时间格式化工具类
const bcrypt = require('bcryptjs'); // 用于加密密码
const sendResponse = require('../utils/response');

// 获取所有用户
exports.getAllUsers = async (req, res, next) => {
  try {
    // 获取分页参数
    const page = parseInt(req.params.page, 10) || 1;
    const limit = parseInt(req.params.limit, 10) || 10;
    // 计算偏移量
    const offset = (page - 1) * limit;
    // 获取搜索用户名
    const { username } = req.query;
    // 如果指定了搜索用户名，则使用 Sequelize 的 where 选项进行搜索
    const where = username ? { username: { [Op.like]: `%${username}%` } } : null;
    // TODO 加密手机号码
    // 调用 User 模型中的方法获取所有用户
    const users = await User.findAndCountAll(
      {
        where,
        as: 'Users',
        limit,
        offset,
        attributes: ['id', 'username', 'name', 'phone', 'roleName', 'createTime', 'updateTime' ],
        // 关联 Role 模型
        include: [{ model: Role, as: 'Roles', attributes: ['id', 'roleName', 'remark'] }], // 关联 Role 模型
        distinct: true, // 确保正确计数主模型
      }
    );
    console.log("---获取用户列表或搜索用户---");

    // 使用改进后的 dateFormatList 函数格式化日期字段
    const formattedUsers = dateFormatter.dateFormatList(users.rows, ['createTime', 'updateTime']);

    // 返回用户列表
    sendResponse(res, { message: '获取用户列表成功', data: {
      records: formattedUsers,
      total: users.count, // 总条数
      size: limit,
      current: page,
      pages: Math.ceil(users.count / limit)
    }});
  } catch (error) {
    console.error('Error fetching users:', error);
    next(error);
  }
};

// 创建用户
exports.createUser = async (req,res,next) => {
  const { username, password, name, phone, rolename } = req.body;

  try {
    // 检查用户名是否已存在
    const existingUser = await User.findOne({
      where: { username: username }
    });
    // TODO 检测手机号码是否已存在

    if (existingUser) {
      return sendResponse(res, { code: 400, message: '用户名已存在！' });
    }

    // 使用 Sequelize 创建新的用户记录
    const newUser = await User.create({
      username,
      password,
      name,
      phone,
      rolename
    });

    // 返回成功响应
    sendResponse(res, { message: '用户创建成功', data: { id: newUser.id, username, name, phone, rolename } });
  } catch (error) {
    console.error('Error creating user:', error);
    next(error);
  }
}

// 更新用户
exports.updateUser = async (req, res,next) => {
  // 获取请求体中的用户信息
  const id = parseInt(req.body.id);
  const { username, password, name } = req.body;

  try {
    // 检查用户是否存在
    const existingUser = await User.findByPk(id);
    if (!existingUser) {
      console.log("---用户id不存在---");
      return sendResponse(res, { code: 404, message: '用户id不存在！' });
    }

    // TODO 检测手机号码是否已存在

    // 如果username是admin，不允许更新
    if (existingUser.username === 'admin') {
      console.log("---admin用户不允许更新---");
      return sendResponse(res, { code: 400, message: 'admin用户不允许更新！' });
    }

    // 检查用户名是否重复
    const existingUserWithSameUsername = await User.findOne({
      where: { username: username }
    });
    if (existingUserWithSameUsername && existingUserWithSameUsername.id !== id) {
      return sendResponse(res, { code: 400, message: '用户名已存在！' });
    }

    // 如果提供了新密码，则加密密码
    const hashedPassword = password
      ? await bcrypt.hash(password, 10)
      : existingUser.password;

    // 更新用户信息
    const updatedUser = await User.update({
      username: username || existingUser.username,
      password: hashedPassword,
      name: name || existingUser.name,
    }, {
      where: { id } // 添加 where 条件
    });
    console.log("---更新用户---");

    // 返回成功响应
    sendResponse(res, { message: '用户更新成功' });
  } catch (error) {
    console.error("Error updating user:", error);
    next(error);
  }
};

// 删除用户
exports.removeUser = async (req, res, next) => {
  // 获取用户 ID
  const id = parseInt(req.params.id);
  
  try {
    // 检查用户是否存在
    const existingUser = await User.findByPk(id);
    if (!existingUser) {
      console.log("---用户不存在---");
      return sendResponse(res, { code: 404, message: '用户不存在！' });
    }
    
    // 如果username是admin，不允许删除
    if (existingUser.username === 'admin') {
      console.log("---admin用户不允许删除---");
      return sendResponse(res, { code: 400, message: 'admin用户不允许删除！' });
    }

    // 检查用户是否有关联的角色
    const userRoles = await existingUser.getRoles();
    if (userRoles.length > 0) {
      console.log("---用户存在关联的角色，无法删除---");
      return sendResponse(res, { code: 400, message: '用户存在关联的角色，无法删除！' });
    }

    // 删除用户
    await User.destroy({
      where: { id } // 指定要删除的记录的条件
    });

    console.log("---删除用户---");
    // 返回成功响应
    sendResponse(res, { message: '用户删除成功' });
  } catch (error) {
    console.error("Error deleting user:", error);
    next(error);
  }
};

// 批量删除用户
exports.batchRemoveUser = async (req, res, next) => {
  // 获取请求体中的用户 ID 数组
  const idList = req.body;
  // console.log(req.body);
  
  try {
    // 检查用户 ID 数组是否为空
    if (idList.length === 0) {
      console.log("---用户 ID 数组为空---");
      return sendResponse(res, { code: 400, message: '用户 ID 数组为空！' });
    }

    // 检查用户 ID 数组中的每个用户是否存在
    const existingUsers = await User.findAll({
      where: { id: idList }
    });
    if (existingUsers.length !== idList.length) {
      console.log("---用户 ID 数组中存在不存在的用户---");
      return sendResponse(res, { code: 400, message: '用户 ID 数组中存在不存在的用户！' });
    }

    // 如果username是admin，不允许删除
    const adminUser = existingUsers.find(user => user.username === 'admin');
    if (adminUser) {
      console.log("---admin用户不允许删除---");
      return sendResponse(res, { code: 400, message: 'admin用户不允许删除！' });
    }

    // 删除用户
    await User.destroy({
      where: { id: idList } // 指定要删除的记录的条件
    });

    console.log("---批量删除用户---");
    // 返回成功响应
    sendResponse(res, { message: '用户批量删除成功' });
  } catch (error) {
    console.error("Error deleting users:", error);
    next(error);
  }

}

// 获取某个用户拥有角色和全部角色
exports.toAssign = async (req, res, next) => {
  try{
    // 获取用户 ID
    const id = parseInt(req.params.id);
    if (isNaN(id)) {
      return sendResponse(res, { code: 400, message: 'Invalid user ID' });
    }
    // 获取所有的角色
    const roles = await Role.findAll({
      attributes: ['id', 'createTime', 'updateTime', 'roleName','remark'],
    });
    // 获取用户拥有的角色
    const user = await User.findByPk(id, {
      include: [{
        model: Role,
        as: 'Roles',
        attributes: ['id', 'createTime', 'updateTime', 'roleName','remark'],
        through: { attributes: [] }, // 去除中间表
      }]
    });
    // 检查用户是否存在
    if (!user) {
      return sendResponse(res, { code: 404, message: 'User not found' });
    }
    // 获取用户拥有的角色
    const userRoles = user.Roles;
    
    const formattedRoles = dateFormatter.dateFormatList(roles, ['createTime', 'updateTime']);
    const formattedUserRoles = dateFormatter.dateFormatList(userRoles, ['createTime', 'updateTime']);
    console.log("---获取用户已有角色和全部角色---");
    
    sendResponse( res, {
      data:{
        assignRoles: formattedUserRoles,
        allRolesList: formattedRoles
      }
    });
  } catch (error) {
    next(error);
  }
}

// 为用户分配角色
exports.doAssignRole = async (req, res, next) => {
  try{
    const { userId, roleIdList } = req.body;
    // 检查用户 ID 是否为数字
    if (isNaN(parseInt(userId))) {
      return sendResponse(res, { code: 400, message: 'Invalid user ID' });
    }
    // 检查角色 ID 数组是否为空
    if (roleIdList.length === 0) {
      return sendResponse(res, { code: 400, message: '角色 ID 数组为空' });
    }
    // 遍历角色 ID 数组，转换整型数值并返回，检查每个角色 ID 是否为数字
    const validRoleIdList = roleIdList.map(roleId => {
      if (isNaN(parseInt(roleId))) {
        return null;
      }
      return parseInt(roleId);
    });
    // 检查角色 ID 数组中是否存在无效的 ID
    if (validRoleIdList.includes(null)) {
      return sendResponse(res, { code: 400, message: '角色 ID 数组中存在无效的 ID' });
    }
    // 给用户分配角色
    const user = await User.findByPk(parseInt(userId));
    await user.setRoles(validRoleIdList);
    console.log("---给用户分配角色成功---");
    
    sendResponse(res, { message: '分配角色成功' });
  } catch (error) {
    next(error);
  }
}